﻿/*
更新日志:
语法更新到sm1.10
添加路程进度
添加重启次数
添加地图运行时间
*/
#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>
#include <left4dhooks>

Handle g_hTimer;
ConVar g_hHostName, g_hGameMode;

char g_sPath[PLATFORM_MAX_PATH];
char g_sFileLine[255];
static const char g_sRound[2][16] =
{
	"[上半场]",
	"[下半场]"
};

bool g_bIsCoop;

float g_fFlowMax;
float g_fHighestFlow;
float g_fMapRunTime;

int g_iFailureCount;

public Plugin myinfo =
{
	name = "L4D2 中文服务器名",
	description = "",
	author = "Naruto[鸭蛋修正], sorallll",
	version = "1.0.0",
	url = "N/A"
};

public void OnPluginStart()
{
	BuildPath(Path_SM, g_sPath, sizeof(g_sPath), "configs/hostname/hostname.txt");
	if(FileExists(g_sPath) == false)
		SetFailState("配置文件configs/hostname/hostname.txt丢失");

	HookEvent("mission_lost", Event_MissionLost, EventHookMode_PostNoCopy);

	g_hHostName = FindConVar("hostname");
	g_hGameMode = FindConVar("mp_gamemode");
	g_hGameMode.AddChangeHook(GameModeChanged);
}

public void OnConfigsExecuted()
{
	g_bIsCoop = IsCoop();
	g_fMapRunTime = GetEngineTime();
	g_iFailureCount = 0;
	g_fFlowMax = L4D2Direct_GetMapMaxFlowDistance();
	g_fHighestFlow = 0.0;
	UpdateHostName();
	delete g_hTimer;
	g_hTimer = CreateTimer(5.0, Timer_UpdateHostName, _, TIMER_REPEAT);
}

public void GameModeChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
	g_bIsCoop = IsCoop();
}

bool IsCoop() 
{
	char sGameMode[16];
	g_hGameMode.GetString(sGameMode, sizeof(sGameMode));
	return strcmp(sGameMode, "versus", false) != 0 && strcmp(sGameMode, "scavenge", false) != 0;
}

public void Event_MissionLost(Event event, const char[] name, bool dontBroadcast)
{
	g_iFailureCount++;
}

public Action Timer_UpdateHostName(Handle timer)
{
	if(!L4D_HasAnySurvivorLeftSafeArea())
		return Plugin_Continue;

	int client = L4D_GetHighestFlowSurvivor();
	if(client > 0)
	{
		g_fHighestFlow = L4D2Direct_GetFlowDistance(client);
		if(g_fHighestFlow)
			g_fHighestFlow = g_fHighestFlow / g_fFlowMax * 100;
	}

	static char sHostName[255];
	sHostName[0] = 0;
	FormatEx(sHostName, sizeof(sHostName), "%s [路程:%.1f%%]", g_sFileLine, g_fHighestFlow);

	static char sRound[32];
	sRound[0] = 0;
	if(g_bIsCoop)
		Format(sHostName, sizeof(sHostName), "%s[重启:%d]", sHostName, g_iFailureCount);
	else
		StrCat(sHostName, sizeof(sHostName), g_sRound[GameRules_GetProp("m_bInSecondHalfOfRound") ? 1 : 0]);

	static char sRunTime[32];
	sRunTime[0] = 0;
	StandardizeTime(GetEngineTime() - g_fMapRunTime, sRunTime);
	StrCat(sHostName, sizeof(sHostName), sRunTime);
	
	g_hHostName.SetString(sHostName);
	return Plugin_Continue;
}

void UpdateHostName()
{
	if(FileExists(g_sPath) == false)
	{
		g_hHostName.SetString(g_sFileLine);
		return;
	}

	File file = OpenFile(g_sPath, "rb");
	if(file)
	{
		while(!file.EndOfFile())
		{
			if(file.ReadLine(g_sFileLine, sizeof(g_sFileLine)))
				g_hHostName.SetString(g_sFileLine);
		}
		delete file;
	}
}

//https://forums.alliedmods.net/showthread.php?t=288686
void StandardizeTime(float time, char str[32])
{
	float remainder = time;
	int h = RoundToFloor(remainder / 3600.0);
	remainder = remainder - float(h * 3600);
	int m = RoundToFloor(remainder / 60.0);
	remainder = remainder - float(m * 60);
	int s = RoundToFloor(remainder);

	FormatEx(str, sizeof(str), "[运行:%dh:%dm:%ds]", h, m, s);
}